package org.lemon.transport.rule.engine.mqtt.config;

import io.netty.channel.Channel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.mqtt.MqttVersion;
import io.netty.handler.ssl.SslContext;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.lemon.transport.rule.engine.mqtt.model.MqttLastWill;

import java.util.Random;

public class MqttClientConfig {

    private final SslContext sslContext;
    private String clientId;

    private int timeoutSeconds = 60;
    private MqttVersion protocolVersion = MqttVersion.MQTT_3_1;
    private String username = null;
    private String password = null;
    private boolean cleanSession = true;
    @Nullable
    private MqttLastWill lastWill;
    private final Class<? extends Channel> channelClass = NioSocketChannel.class;

    private boolean reconnect = true;
    private long reconnectDelay = 1L;
    private int maxBytesInMessage = 8092;

    public MqttClientConfig() {
        this(null);
    }

    public MqttClientConfig(SslContext sslContext) {
        this.sslContext = sslContext;
        this.clientId = randomClientId();
    }

    @NonNull
    public String getClientId() {
        return clientId;
    }

    public int getTimeoutSeconds() {
        return timeoutSeconds;
    }

    public void setTimeoutSeconds(int timeoutSeconds) {
        if (timeoutSeconds != -1 && timeoutSeconds <= 0) {
            throw new IllegalArgumentException("timeoutSeconds must be > 0 or -1");
        }
        this.timeoutSeconds = timeoutSeconds;
    }

    public MqttVersion getProtocolVersion() {
        return protocolVersion;
    }

    public void setProtocolVersion(MqttVersion protocolVersion) {
        if (protocolVersion == null) {
            throw new NullPointerException("protocolVersion");
        }
        this.protocolVersion = protocolVersion;
    }

    @Nullable
    public String getUsername() {
        return username;
    }

    public void setUsername(@Nullable String username) {
        this.username = username;
    }

    @Nullable
    public String getPassword() {
        return password;
    }

    public void setPassword(@Nullable String password) {
        this.password = password;
    }

    public boolean isCleanSession() {
        return cleanSession;
    }

    public void setCleanSession(boolean cleanSession) {
        this.cleanSession = cleanSession;
    }

    public int getMaxBytesInMessage() {
        return maxBytesInMessage;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public SslContext getSslContext() {
        return sslContext;
    }

    public boolean isReconnect() {
        return reconnect;
    }

    public void setReconnect(boolean reconnect) {
        this.reconnect = reconnect;
    }

    public long getReconnectDelay() {
        return reconnectDelay;
    }

    public void setReconnectDelay(long reconnectDelay) {
        this.reconnectDelay = reconnectDelay;
    }

    /**
     * 设置消息最大字节数, 默认为 8092 bits,  最大不能超过256MB
     */
    public void setMaxBytesInMessage(int maxBytesInMessage) {
        if (maxBytesInMessage <= 0 || maxBytesInMessage > 256_000_000) {
            throw new IllegalArgumentException("maxBytesInMessage must be > 0 or < 256_000_000");
        }
        this.maxBytesInMessage = maxBytesInMessage;
    }

    private String randomClientId() {

        Random random = new Random();
        StringBuilder id = new StringBuilder("netty-mqtt/");
        final String[] options = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".split("");
        for (int i = 0; i < 8; i++) {
            id.append(options[random.nextInt(options.length)]);
        }
        return id.toString();
    }
}
